xl: Add "seize" option to PCI devices
authorGeorge Dunlap <george.dunlap@eu.citrix.com>
Tue, 4 Mar 2014 13:38:19 +0000 (13:38 +0000)
committerIan Jackson <Ian.Jackson@eu.citrix.com>
Mon, 10 Mar 2014 12:03:59 +0000 (12:03 +0000)
The "seize" option tells the toolstack to attempt to automatically
unbind devices and re-bind them to the pciback driver.  This should
make creating VMs that habitually use pass-through (such as driver domain
VMs and gaming VMs) easier to use and manage.

[Whitespace error fixed by iwj.]

Signed-off-by: George Dunlap <george.dunlap@eu.citrix.com>
docs/man/xl.cfg.pod.5
tools/libxl/libxl_pci.c
tools/libxl/libxl_types.idl
tools/libxl/libxlu_pci.c
tools/libxl/xl_cmdimpl.c

index e15a49f69cad997bc5d42632f1e573b4d6e6d0ee..c02ad5593f569971a7e5fdc3702498ea26436369 100644 (file)
@@ -509,6 +509,15 @@ the PCI device regardless whether the guest uses INTx or MSI. Some
 device drivers, such as NVIDIA's, detect an inconsistency and do not
 function when this option is enabled. Therefore the default is false (0).
 
+=item B<seize=BOOLEAN>
+
+Tells xl to automatically attempt to re-assign a device to
+pciback if it is not already assigned.
+
+WARNING: If you set this option, xl will gladly re-assign a critical
+system device, such as a network or a disk controller being used by
+dom0 without confirmation.  Please use with care.
+
 =item B<power_mgmt=BOOLEAN>
 
 (HVM only) Specifies that the VM should be able to program the
@@ -530,6 +539,11 @@ above.
 Changes the default value of 'msitranslate' for all PCI devices passed
 through to this VM. See L<msitranslate|/"msitranslate_boolean"> above.
 
+=item B<pci_seize=BOOLEAN>
+
+Changes the default value of 'seize' for all PCI devices passed
+through to this VM. See L<seize|/"seize_boolean"> above.
+
 =item B<pci_power_mgmt=BOOLEAN>
 
 (HVM only) Changes the default value of 'power_mgmt' for all PCI
index 2e5247031a98cea3a97bccc58c0f60f366bb71ba..44d04539eae3a2e56dcdb3d4bfbe9000881252e2 100644 (file)
@@ -1050,6 +1050,12 @@ int libxl__device_pci_add(libxl__gc *gc, uint32_t domid, libxl_device_pci *pcide
     rc = libxl__device_pci_setdefault(gc, pcidev);
     if (rc) goto out;
 
+    if (pcidev->seize && !pciback_dev_is_assigned(gc, pcidev)) {
+        rc = libxl__device_pci_assignable_add(gc, pcidev, 1);
+        if ( rc )
+            goto out;
+    }
+
     if (!libxl_pcidev_assignable(ctx, pcidev)) {
         LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "PCI device %x:%x:%x.%x is not assignable",
                    pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func);
index 649ce501ff0c0199062f8109a08ad1e0282e3cea..7d3a62b3aea9cbc63eae1a9d237d8c8e76802301 100644 (file)
@@ -444,6 +444,7 @@ libxl_device_pci = Struct("device_pci", [
     ("msitranslate", bool),
     ("power_mgmt", bool),
     ("permissive", bool),
+    ("seize", bool),
     ])
 
 libxl_device_vtpm = Struct("device_vtpm", [
index f5dee93b7918e3eb332c1a14b0776803bd9cc1bf..26fb143d389da8bf18d92725eaa88054dd5c4e2e 100644 (file)
@@ -141,6 +141,8 @@ int xlu_pci_parse_bdf(XLU_Config *cfg, libxl_device_pci *pcidev, const char *str
                     pcidev->power_mgmt = atoi(tok);
                 }else if ( !strcmp(optkey, "permissive") ) {
                     pcidev->permissive = atoi(tok);
+                }else if ( !strcmp(optkey, "seize") ) {
+                    pcidev->seize = atoi(tok);
                 }else{
                     XLU__PCI_ERR(cfg, "Unknown PCI BDF option: %s", optkey);
                 }
index 4fc46eb26b7d2fc7224f7f054e7578e0fa974d1e..5f59bbccc2ed9680a5e7f9352c91fac55b52b756 100644 (file)
@@ -737,6 +737,7 @@ static void parse_config_data(const char *config_source,
     int pci_power_mgmt = 0;
     int pci_msitranslate = 0;
     int pci_permissive = 0;
+    int pci_seize = 0;
     int i, e;
 
     libxl_domain_create_info *c_info = &d_config->c_info;
@@ -1462,6 +1463,9 @@ skip_vfb:
     if (!xlu_cfg_get_long (config, "pci_permissive", &l, 0))
         pci_permissive = l;
 
+    if (!xlu_cfg_get_long (config, "pci_seize", &l, 0))
+        pci_seize = l;
+
     /* To be reworked (automatically enabled) once the auto ballooning
      * after guest starts is done (with PCI devices passed in). */
     if (c_info->type == LIBXL_DOMAIN_TYPE_PV) {
@@ -1481,6 +1485,7 @@ skip_vfb:
             pcidev->msitranslate = pci_msitranslate;
             pcidev->power_mgmt = pci_power_mgmt;
             pcidev->permissive = pci_permissive;
+            pcidev->seize = pci_seize;
             if (!xlu_pci_parse_bdf(config, pcidev, buf))
                 d_config->num_pcidevs++;
         }